package com.baidu.infinity.ui.fragment.home.shape

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.RectF
import android.graphics.Region
import com.baidu.infinity.R
import com.baidu.infinity.ui.util.state.ShapeState
import com.baidu.infinity.ui.util.dp2px

abstract class BaseShape() {
    var mState = ShapeState.NORMAL
    var startX: Float = 0f
    var endX: Float = 0f
    var startY: Float = 0f
    var endY: Float = 0f
    var centerX: Float = 0f
    var centerY: Float = 0f
    val rectF = RectF()
    var mPath = Path()
    var mSelectedState = SelectState.NONE
    var mStartMoveX: Float = 0f
    var mStartMoveY: Float = 0f
    var mMoveDX: Float = 0f
    var mMoveDY: Float = 0f
    val mCornerBitmap: Bitmap by lazy {
        BitmapFactory.decodeResource(
            LayerManager.instance.context!!.resources,
            R.drawable.scale_corner
        )
    }
    val mCornerSize: Int by lazy {
        LayerManager.instance.context!!.dp2px(12)
    }
    val mPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        strokeCap = Paint.Cap.ROUND
        strokeJoin = Paint.Join.ROUND
        color = LayerManager.instance.mColor
        strokeWidth = LayerManager.instance.mStrockSize
        style = LayerManager.instance.mStrokeStyle
    }
    val mOutLinePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.RED
        style = Paint.Style.STROKE
        strokeWidth = 10f
    }
    open fun setStartPoint(startX: Float, startY: Float){
        this.startX = startX
        this.startY = startY

    }
    open fun setEndPoint(endX: Float, endY: Float){
        this.endX = endX
        this.endY = endY
        this.centerX = (startX + endX) / 2
        this.centerY = (startY + endY) / 2
        rectF.left = Math.min(this.startX,this.endX)
        rectF.right = Math.max(this.startX,this.endX)
        rectF.top = Math.min(this.startY,this.endY)
        rectF.bottom = Math.max(this.startY,this.endY)
    }
    fun updateState(){
        if(mState == ShapeState.SELECT)return
        if(mState == ShapeState.NORMAL){
            mState = ShapeState.DRAWING
        }else{
            mState = ShapeState.NORMAL
        }
    }
    open fun draw(canvas: Canvas){
        if(mState == ShapeState.SELECT){
            canvas.drawRect(rectF.left - 5,rectF.top - 5,rectF.right + 5,rectF.bottom + 5,mOutLinePaint)
            canvas.drawBitmap(mCornerBitmap,rectF.left - mCornerSize / 2,rectF.top - mCornerSize / 2,null)
            canvas.drawBitmap(mCornerBitmap,rectF.left - mCornerSize / 2,rectF.bottom - mCornerSize / 2,null)
            canvas.drawBitmap(mCornerBitmap,rectF.right - mCornerSize / 2,rectF.top - mCornerSize / 2,null)
            canvas.drawBitmap(mCornerBitmap,rectF.right - mCornerSize / 2,rectF.bottom - mCornerSize / 2,null)
        }

    }
    open fun containsPoint(x: Float,y: Float): Boolean{
        val pathRegion = Region()
        val clipRegion = Region(
            rectF.left.toInt(),
            rectF.top.toInt(),
            rectF.right.toInt(),
            rectF.bottom.toInt()
        )
        pathRegion.setPath(mPath,clipRegion)
        return pathRegion.contains(x.toInt(),y.toInt())
    }
    open fun containsPointInRect(x: Float,y: Float): Boolean{
        val rect = RectF(
            rectF.left - mCornerSize / 2 ,
            rectF.top - mCornerSize / 2,
            rectF.right + mCornerSize / 2,
            rectF.bottom + mCornerSize / 2,
        )

        return rect.contains(x,y)
    }
    open fun updateSelectState(x: Float,y: Float){
        mStartMoveX = x
        mStartMoveY = y
        if(x in rectF.left - mCornerSize * 2 ..rectF.left + mCornerSize  * 2 && y in rectF.top - mCornerSize * 2.. rectF.top + mCornerSize * 2){
            mSelectedState = SelectState.LEFT_TOP
        }else if (x in rectF.left - mCornerSize  * 2 ..rectF.left + mCornerSize * 2 && y in rectF.bottom - mCornerSize * 2.. rectF.bottom + mCornerSize * 2){
            mSelectedState = SelectState.LEFT_BOTTOM
        }else if (x in rectF.right - mCornerSize  * 2 ..rectF.right + mCornerSize * 2 && y in rectF.top - mCornerSize * 2.. rectF.top + mCornerSize * 2){
            mSelectedState = SelectState.RIGHT_TOP
        }else if (x in rectF.right - mCornerSize  * 2 ..rectF.right + mCornerSize * 2&& y in rectF.bottom - mCornerSize * 2.. rectF.bottom + mCornerSize * 2){
            mSelectedState = SelectState.RIGHT_BOTTOM
        }else if (x in rectF.left - mCornerSize / 2 ..rectF.left + mCornerSize / 2){
            mSelectedState = SelectState.LEFT
        }else if (x in rectF.right - mCornerSize / 2 ..rectF.right + mCornerSize / 2){
            mSelectedState = SelectState.RIGHT
        }else if (y in rectF.top - mCornerSize / 2 ..rectF.top + mCornerSize / 2){
            mSelectedState = SelectState.TOP
        }else if (y in rectF.bottom - mCornerSize / 2 ..rectF.bottom + mCornerSize / 2){
            mSelectedState = SelectState.BOTTOM
        }else{
            mSelectedState = SelectState.CENTER
        }
    }
    open fun calculateLotation(x: Float,y: Float){
        mMoveDX = x - mStartMoveX
        mMoveDY = y - mStartMoveY
        if(mSelectedState == SelectState.LEFT_TOP){
            moveLeft(x,y)
            moveTop(x,y)
        }else if (mSelectedState == SelectState.LEFT_BOTTOM){
            moveLeft(x,y)
            moveBottom(x,y)
        }else if (mSelectedState == SelectState.RIGHT_TOP){
            moveRight(x,y)
            moveTop(x,y)
        }else if (mSelectedState == SelectState.RIGHT_BOTTOM){
            moveRight(x,y)
            moveBottom(x,y)
        }else if (mSelectedState == SelectState.LEFT){
            moveLeft(x,y)
        }else if (mSelectedState == SelectState.TOP){
            moveTop(x,y)
        }else if (mSelectedState == SelectState.RIGHT){
            moveRight(x,y)
        }else if (mSelectedState == SelectState.BOTTOM){
            moveBottom(x,y)
        }else if (mSelectedState == SelectState.CENTER){
            rectF.offset(mMoveDX,mMoveDY)
            mStartMoveX = x
            mStartMoveY = y
        }
        restorePointLocation()
    }
    private fun restorePointLocation(){
        if(startX < endX && startY < endY){
            startX = rectF.left
            startY = rectF.top
            setEndPoint(rectF.right,rectF.bottom)
        }else if (startX > endX && startY < endY){
            startX = rectF.right
            startY = rectF.top
            setEndPoint(rectF.left,rectF.bottom)
        }else if (startX < endX && startY > endY){
            startX = rectF.left
            startY = rectF.bottom
            setEndPoint(rectF.right,rectF.top)
        }else{
            startX = rectF.right
            startY = rectF.bottom
            setEndPoint(rectF.left,rectF.top)
        }
    }
    fun moveLeft(x: Float,y: Float){
        if(startX < endX){
            startX = x
        }else{
            endX = x
        }
        rectF.left = x
    }
    fun moveRight(x: Float,y: Float){
        if(startX < endX){
            endX = x
        }else{
            startX = x
        }
        rectF.right = x
    }
    fun moveTop(x: Float,y: Float){
        if(startY < endY){
            startY = y
        }else{
            endY = y
        }
        rectF.top = y
    }
    fun moveBottom(x: Float,y: Float){
        if(startY < endY){
            endY = y
        }else{
            startY = y
        }
        rectF.bottom = y
    }
    open fun fillColor(){
        mPaint.color = LayerManager.instance.mColor
    }
    enum class SelectState{
        NONE,
        CENTER,
        LEFT_TOP,
        RIGHT_TOP,
        LEFT_BOTTOM,
        RIGHT_BOTTOM,
        LEFT,
        RIGHT,
        TOP,
        BOTTOM
    }

}